import java.io.Serializable;


//HShin, 4/9/13
public class TaskObj implements Serializable{

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private int taskId;          // this task ID
    
    private int taskMemSize;	// memory size to execute tasks, memory
    private int taskFileSize;   // in byte = program + input data size, disk size
    private int cpuNum;           // num of sec required to execute this job on 1 CPU
    private int lan;				// bandwidth needed for this job
	private double price;
	private double costperLan;		//file transfer cost

    private double finishTime;      // the time where this task ended
    private double startTime;		// the time where this task started
    private static double clock;
    public double submissionTime;

    private int vmId;				// VM ID that this task is assigned to 
    private int vmType;				// VM Type that this task is assigned to    
    
    private int status;             // status of this application    
    private int index;
    private int userId;	//client ID
    
    //Below is Tags to check the status of Tasks needed for different allocation cases
    public static final int CREATED = 0;
    public static final int READY = 1;
    public static final int QUEUED = 2;
    public static final int SUCCESS = 3;
    public static final int FAILED = 4;
    public static final int CANCELED = 5;

    public TaskObj() {
        this.userId = -1;
        this.status = CREATED;
        this.startTime = 0.0;
        this.finishTime = -1.0;    // this task hasn't finished yet
        this.submissionTime = 0.0; //submission time to different cloud resources

        // Task's memory size, file size should be at least 1 byte.
        this.taskMemSize = Math.max(1, taskMemSize);
        this.taskFileSize = Math.max(1, taskFileSize);

		this.vmId = -1;
		this.vmType = -1;
		this.price = 0.0;
		this.costperLan = 0.0;		
	}

	public TaskObj(int taskId, int taskMemSize, int cpuNum, int taskFileSize, int lan) {
        this.userId = -1;
        this.status = CREATED;
        this.taskId = taskId;
        this.cpuNum = cpuNum;
        this.lan = lan;
        this.startTime = 0.0;
        this.finishTime = -1.0;    // this task hasn't finished yet
        this.submissionTime = 0.0; //submission time to different cloud resources

        // Task's memory size, file size should be at least 1 byte.
        this.taskMemSize = Math.max(1, taskMemSize);
        this.taskFileSize = Math.max(1, taskFileSize);

		this.vmId = -1;
		this.vmType = -1;
		this.price = 0.0;
		this.costperLan = 0.0;		
	}

	public boolean setTaskMemSize(int taskMemSize) {
        if (taskMemSize <= 0) {
            return false;
        }
        this.taskMemSize = taskMemSize;
        return true;
    }
	
	public int getTaskMemSize() {
		return taskMemSize;
	}

	public int getTaskId() {
		return taskId;
	}

	public void setTaskId(int taskId) {
		this.taskId = taskId;
	}
	
	public int getUserId() {
		return userId;
	}

	public void setUserId(int userId) {
		this.userId = userId;
	}

	public int getTaskFileSize() {
		return taskFileSize;
	}

	public void setTaskFileSize(int taskFileSize) {
		this.taskFileSize = taskFileSize;
	}

	public int getLan() {
		return lan;
	}

	public void setLan(int lan) {
		this.lan = lan;
	}

	public double getUnitPrice() {
		return price;
	}

	public void setUnitPrice(double price) {
		this.price = price;
	}
	
	public double getCostperLan() {
		return costperLan;
	}

	public void setCostperlan(double costperLan) {
		this.costperLan = costperLan;
	}

	 //Gets the total cost of processing this TaskObj
    public double getProcessingPrice() {
    	double price = getUnitPrice();
		price += this.costperLan * getTaskFileSize();
        return price;
    }
	
	
	public double getStartTime() {
		return startTime;
	}

	public static double clock() {
		return clock;
	}
	
	public void setStartTime(double clockTime) {
		this.startTime = clockTime;
	}
	public void setStartTime() {
		this.startTime = clock();
	}
	
	public double getFinishTime() {
		return finishTime;
	}
	
	public void setFinishTime(double finishTime) {
		this.finishTime = finishTime;
	}

	public double getTotalExectime() {
		return getFinishTime() - getStartTime();
	}

    //Sets the submission time of this TaskObj into a Cloud Resource.
    public void setSubmissionTime(double clockTime) {
        if (clockTime < 0.0 || index < 0) {
            return;
        }     
        submissionTime = clockTime;
    }
	
	public boolean setCpuNum(int cpuNum) {
		if (cpuNum > 0) {
			this.cpuNum = cpuNum;
			return true;
		}
		return false;
	}

	public int getCpuNum() {
		return cpuNum;
	}
   
  //Gets the total memory size of this Task.
    public long getTaskTotalMem() {
        return getTaskMemSize() * getCpuNum();
    }
    
    public int getVmId(){
    	return vmId;
    }
    
	public void setVmId(int vmId) {
		this.vmId = vmId;
	}
    
    public int getVmType(){
    	return vmType;
    }
    
	public void setVmType(int vmType) {
		this.vmType = vmType;
	}
    
    
	public void setStatus(int status) {
		this.status = status;
	}
	
    public String getTaskObjStatusString() {
        return TaskObj.getStatusString(status);
    }

    public static String getStatusString(final int status) {
        String statusString = null;
        switch (status)
        {
            case TaskObj.CREATED:
                statusString = "Created";
                break;
            case TaskObj.READY:
                statusString = "Ready";
                break;
            case TaskObj.SUCCESS:
                statusString = "Success";
                break;
            case TaskObj.QUEUED:
                statusString = "Queued";
                break;
            case TaskObj.FAILED:
                statusString = "Failed";
                break;
            case TaskObj.CANCELED:
                statusString = "Canceled";
                break;
            default:
                break;
        }
        return statusString;
    }
    
}